﻿using OpenTK.Graphics.ES30;
using OpenTK.WinForms;
using ttbit.WorkingSpace;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using ttbit.core;
using pixeleditor.Editor;

namespace spriteeditor.Renderer
{

    public class TTRender2
    {
        EditorApp editorapp;
        public GLControl Init(System.Windows.Forms.Control parent)
        {
            var setn = GLControlSettings.Default.Clone();
            setn.APIVersion = new System.Version(3, 0, 0, 0);
            setn.API = OpenTK.Windowing.Common.ContextAPI.OpenGLES;
            var glc = new OpenTK.WinForms.GLControl(setn);
            parent.Controls.Add(glc);
            glc.Dock = DockStyle.Fill;

            var glver = GL.GetString(StringName.Version);


            ttbit.core.Env.GL = new ttbit.Windows.GLWin();
            ttbit.core.CoreResource.Init();

            render = new QuadBatchRenderer();
            commonparam = new CommonRenderParam();

            matOne = new ttbit.core.Material(ShaderPool.GetShader("base"));
            matOne.texMain = TexturePool.WhiteTexture;

            return glc;

        }
        float v = 0;

        Material matOne;
        QuadBatchRenderer render;
        CommonRenderParam commonparam;
        int screenWidth;
        int screenHeight;
        int framecount;
        float timer = 0;
        DateTime last = DateTime.Now;
        public int fps
        {
            get;
            private set;
        }
        float UpdateFps()
        {
            var now = DateTime.Now;
            var delta = (float)(now - last).TotalSeconds;
            last = now;
            framecount++;
            timer += delta;
            if (timer > 1.0f)
            {
                fps = framecount;
                timer -= 1.0f;
                framecount = 0;

            }
            return delta;

        }
        public void BeginRender(int width, int height)
        {
            UpdateFps();


            screenWidth = width;
            screenHeight = height;
            GL.Viewport(0, 0, width, height);
            v += 1.0f / 255;
            if (v > 2.0) v = 0;
            var c = v;
            if (c > 1.0f) c = 2.0f - c;
            GL.ClearColor(c * 0.5f, c * 0.5f, c * 0.25f, 1);
            GL.Clear(ClearBufferMask.ColorBufferBit);


            commonparam.matProj.Mat3Proj(width, height, true);

            matOne.UpdateContext(commonparam);


            render.EndFrame();
        }
        public void EndRender()
        {
            render.EndFrame();
        }
        int lineheight = 0;
        //void DrawSprites(List<SkinSprite> sprites)
        //{
        //    var x = 0;
        //    var y = 0;
        //    foreach (var s in sprites)
        //    {
        //        var tex = editorapp.resmgr.GetTexture(s.filename);
        //        matOne.texMain = tex;
        //        if (s.uv.Width < 0)
        //            s.uv.Width = tex.Width;
        //        if (s.uv.Height < 0)
        //            s.uv.Height = tex.Height;

        //        var width = (int)(s.uv.Width * workspace.usermode_scale);
        //        var height = (int)(s.uv.Height * workspace.usermode_scale);

        //        if (lineheight < height)
        //            lineheight = height;

        //        DrawRect(x, y, x + width, y + height, matOne, s.uv);
        //        x += width;
        //        if (x > screenWidth)
        //        {
        //            x = 0;
        //            y += lineheight;
        //            lineheight = 0;
        //        }
        //    }
        //}
        //void DrawSpritesMode2Cross(List<SkinSprite> sprites)
        //{
        //    var x = 16;
        //    var y = 16;
        //    foreach (var s in sprites)
        //    {
        //        var tex = workspace.GetTexture(s.filename);
        //        matOne.texMain = tex;
        //        if (s.uv.Width < 0)
        //            s.uv.Width = tex.Width;
        //        if (s.uv.Height < 0)
        //            s.uv.Height = tex.Height;

        //        var width = (int)(s.uv.Width * workspace.usermode_scale);
        //        var height = (int)(s.uv.Height * workspace.usermode_scale);


        //        if (lineheight < height)
        //            lineheight = height;

        //        //十字线闪烁变量
        //        float b = (v * 10) % 2.0f;
        //        if (b > 1.0f) b = 2 - b;
        //        DrawCross(x + (int)(s.povit.X * workspace.usermode_scale), y + (int)(s.povit.Y * workspace.usermode_scale), (int)(100 * workspace.usermode_scale), (int)workspace.usermode_scale, ttbit.math.ColorF.FromARGB(b, b, b, b));

        //        if (workspace.usermode_editsprite != null && workspace.usermode_editsprite.sprite == s && workspace.usermode_editsprite.Povit != s.povit)
        //        {
        //            var px = workspace.usermode_editsprite.Povit.X;
        //            var py = workspace.usermode_editsprite.Povit.Y;
        //            DrawCross(x + (int)(px * workspace.usermode_scale), y + (int)(py * workspace.usermode_scale), (int)(100 * workspace.usermode_scale), (int)workspace.usermode_scale, ttbit.math.ColorF.FromARGB(b, b, 0, 0));

        //        }
        //        x += width + 4;
        //        if (x > screenWidth)
        //        {
        //            x = 0;
        //            y += lineheight + 4;
        //            lineheight = 0;
        //        }
        //    }
        //}
        //void DrawSpritesMode2(List<SkinSprite> sprites)
        //{
        //    var x = 16;
        //    var y = 16;
        //    foreach (var s in sprites)
        //    {
        //        var tex = workspace.GetTexture(s.filename);
        //        matOne.texMain = tex;
        //        if (s.uv.Width < 0)
        //            s.uv.Width = tex.Width;
        //        if (s.uv.Height < 0)
        //            s.uv.Height = tex.Height;

        //        var width = (int)(s.uv.Width * workspace.usermode_scale);
        //        var height = (int)(s.uv.Height * workspace.usermode_scale);


        //        if (lineheight < height)
        //            lineheight = height;

        //        DrawRect(x, y, x + width, y + height, matOne, s.uv);
        //        DrawBorder(x, y, x + width, y + height, 1, ttbit.math.ColorF.FromARGB(1, 1, 1, 0));

        //        x += width + 4;
        //        if (x > screenWidth)
        //        {
        //            x = 0;
        //            y += lineheight + 4;
        //            lineheight = 0;
        //        }
        //    }
        //}
        Material matBorder;
        public void DrawBorder(int x, int y, int x2, int y2, int w, ttbit.math.ColorF color)
        {
            if (matBorder == null)
                matBorder = new ttbit.core.Material(ShaderPool.GetShader("color"));
            matBorder.texMain = TexturePool.WhiteTexture;
            matBorder.color = color;
            matBorder.UpdateContext(this.commonparam);
            DrawRect(x, y, x2, y + w, matBorder, new Rectangle(0, 0, 2, 2));
            DrawRect(x, y2, x2, y2 + w, matBorder, new Rectangle(0, 0, 2, 2));
            DrawRect(x, y, x + w, y2, matBorder, new Rectangle(0, 0, 2, 2));
            DrawRect(x2, y, x2 + w, y2, matBorder, new Rectangle(0, 0, 2, 2));
        }
        public void DrawCross(int x, int y, int size, int w, ttbit.math.ColorF color)
        {
            if (matBorder == null)
                matBorder = new ttbit.core.Material(ShaderPool.GetShader("color"));
            matBorder.texMain = TexturePool.WhiteTexture;
            matBorder.color = color;
            matBorder.UpdateContext(this.commonparam);
            DrawRect(x - size, y, x + size, y + w, matBorder, new Rectangle(0, 0, 2, 2));
            DrawRect(x, y - size, x + w, y + size, matBorder, new Rectangle(0, 0, 2, 2));
        }
        public void DrawTexture(int x, int y, int x2, int y2, Texture tex, Rectangle uv)
        {
            matOne.texMain = tex;
            DrawRect(x, y, x2, y2, matOne, uv);
        }
        void DrawRect(int x, int y, int x2, int y2, Material mat, Rectangle uv)
        {
            var r1 = render.ReqBuf(1, mat);

            var i0 = r1.seek + 0;
            r1.buffer[r1.seek + 0].X = x;
            r1.buffer[r1.seek + 0].Y = y;
            r1.buffer[r1.seek + 0].R = 255;
            r1.buffer[r1.seek + 0].G = 255;
            r1.buffer[r1.seek + 0].B = 255;
            r1.buffer[r1.seek + 0].A = 255;
            r1.buffer[r1.seek + 0].U = (float)uv.X / (mat.texMain == null ? 1 : mat.texMain.Width);
            r1.buffer[r1.seek + 0].V = (float)uv.Y / (mat.texMain == null ? 1 : mat.texMain.Height);

            r1.buffer[r1.seek + 1].X = x2;
            r1.buffer[r1.seek + 1].Y = y;
            r1.buffer[r1.seek + 1].R = 255;
            r1.buffer[r1.seek + 1].G = 255;
            r1.buffer[r1.seek + 1].B = 255;
            r1.buffer[r1.seek + 1].A = 255;
            r1.buffer[r1.seek + 1].U = (float)(uv.X + uv.Width) / (mat.texMain == null ? 1 : mat.texMain.Width);
            r1.buffer[r1.seek + 1].V = (float)uv.Y / (mat.texMain == null ? 1 : mat.texMain.Height); ;

            r1.buffer[r1.seek + 2].X = x;
            r1.buffer[r1.seek + 2].Y = y2;
            r1.buffer[r1.seek + 2].R = 255;
            r1.buffer[r1.seek + 2].G = 255;
            r1.buffer[r1.seek + 2].B = 255;
            r1.buffer[r1.seek + 2].A = 255;
            r1.buffer[r1.seek + 2].U = (float)(uv.X) / (mat.texMain == null ? 1 : mat.texMain.Width);
            r1.buffer[r1.seek + 2].V = (float)(uv.Y + uv.Height) / (mat.texMain == null ? 1 : mat.texMain.Height); ;

            r1.buffer[r1.seek + 3].X = x2;
            r1.buffer[r1.seek + 3].Y = y2;
            r1.buffer[r1.seek + 3].R = 255;
            r1.buffer[r1.seek + 3].G = 255;
            r1.buffer[r1.seek + 3].B = 255;
            r1.buffer[r1.seek + 3].A = 255;
            r1.buffer[r1.seek + 3].U = (float)(uv.X + uv.Width) / (mat.texMain == null ? 1 : mat.texMain.Width);
            r1.buffer[r1.seek + 3].V = (float)(uv.Y + uv.Height) / (mat.texMain == null ? 1 : mat.texMain.Height); ;
            render.EndFrame();
        }

    }

}
